home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 576-600 / disk_587 / conlib / procdoc.art < prev    next >
Text File  |  1992-05-06  |  30KB  |  873 lines

  1. *******************************************************************************
  2. *                                                                             *
  3. *                            Program Documentation                            *
  4. *                                                                             *
  5. *******************************************************************************
  6.  
  7.  
  8.                        Copyright © 1991 by Bjørn Reese.
  9.  
  10.  
  11. This article may be distributed freely, as long as no charge is being made.
  12. Please note that the article is copyrighted, and may not be changed in any way
  13. without the knowledge and written approval of the author (address is stated
  14. somewhere below).
  15.  
  16. Before we go on, I would like to apologize for any grammatical and spelling
  17. mistake, which you without doubt will encounter.  This article was originally
  18. written in danish for a danish magazine.  I later decided to translate it to a
  19. more universal language in the hope more people could benefit from it.
  20.  
  21. The article presents some principles of how to make useful, understandable and
  22. self-evident names for labels, and how to comment sources.
  23.  
  24. The article is specifically aimed at Amiga (M680x0) assembly programmers, but
  25. I believe that other programmers also may find something useful in the basic
  26. principles of the convention defined in this article.
  27.  
  28.  
  29. *******************************************************************************
  30.                                    Contents
  31. *******************************************************************************
  32.  
  33.         1. Introduction
  34.         2. Comments
  35.         3. Procedures
  36.         4. Variables
  37.         5. Constants
  38.         6. Various (Instructions, Assembly Directives & Macros)
  39.         7. Final Words
  40.  
  41.  
  42. *******************************************************************************
  43.                                 1. Introduction
  44. *******************************************************************************
  45.  
  46. The purpose of this article is to present some guidelines for internal
  47. documentation of sources, i.e. comments and name assignment of labels
  48. (procedures, variables, constants etc.), which makes more readable sources.
  49. This text is primary aimed at Amiga assembly programmers, but other programmers
  50. may also study the basic priciples with advantage.  The guidelines have been
  51. developed and tested over a longer period of time by yours truly.  It may take
  52. some time to get used with them, but it's worth while in the long run.
  53.  
  54. Whenever I use the term "procedure", it refers to a subroutine with a clearly
  55. limited and well-defined function.  For instance, if I wanted to make a
  56. program, which sorts the contents of a file, it would consist of three
  57. procedures.  The first procedure gets the file, the second sorts it and finally
  58. the third saves the result.  We got three clearly limited and well-defined
  59. functions.  These may be split into more procedures, like the sorting, which
  60. consists of an initializing part and a sorting part.
  61.  
  62. Big sources offers an exellent opportunity to loose the general view,
  63. especially if you havn't been engaged in the program for some time and perhaps
  64. developed and/or changed your programming style.  The situation is even worse
  65. if you have to decipher the sources of another programmer.  Lack of
  66. documentation often put us in a situation where a disassembly would have been
  67. just as good as the source, and that is quite unsatisfactory.
  68.  
  69. An unlucky habit of many programmers is, that they don't bother to write very
  70. much besides the instructions.  Their sources contains a minimum of comments
  71. (if any) and short, meaningless names of procedures, variables and constants.
  72.  
  73. Whenever you write comments or name labels, THINK about what you write.  It
  74. is important to find something descriptive, significant and relevant to the
  75. matter.  In the long run it pays to sit and consider, before you write any
  76. comments or name your labels.
  77.  
  78. Unfortunately I often witness "over-abbreviations", that is abbreviations which
  79. are so extreme that there is no way telling what the abbreviation originally
  80. represented.  For instance:
  81.  
  82.     "r"    = "Rollover"
  83.     "sfc1" = "Star Field Counter 1"
  84.  
  85. Non-english people should also be alerted about mixing english and their native
  86. language.  It is almost impossible to decipher these abbreviations.  Please
  87. keep a clear style in your comments and labels.
  88.  
  89.  
  90. *******************************************************************************
  91.                                   2. Comments
  92. *******************************************************************************
  93.  
  94. If other people should be able to read your sources, it is important to include
  95. as many explanatory comments as possible.  You should also be able to profit by
  96. comments in your own sources.  If you return to a source of yours after a
  97. certain period of time, it takes at least a couple of centuries to regain the
  98. necessary knowledge of the source (believe me, I am talking from experience!).
  99. With efficient comments this time can be considerably reduced.
  100.  
  101. While developing a program, you are completely familiar with the problematic of
  102. your program and it may seem unnessesary to make comments of something which
  103. seems so obvious.  But it is worth while, because something that seems so
  104. obvious during development, seldom seem so obvious a couple of weeks or months
  105. later.  Also, the "obvious" may not seem so obvious to other programmers, who
  106. don't have the same knowledge, experience and/or thoughts as yourself.
  107.  
  108. It is however also easy to go to the other extreme, and make meaningless and
  109. superfluous comments which most often confuses more than it helps whose who
  110. read your sources.
  111.  
  112. Example of a meaningless comment:
  113.  
  114.         move.l  d4,a0           ;Dingdong!
  115.  
  116. Example of a superfluous comment:
  117.  
  118.         add.w   #14,d0          ;Add 14 to D0
  119.  
  120. One of the best and most efficient ways to document sources is a header, i.e.
  121. a introductory comment of a procedure or parts of a procedure.  This header
  122. must include information about what this procedure does, what input is required
  123. and what output is delivered.  The header may also include more informations,
  124. like a pseudocode for the procedure or parts of it, references, general
  125. comments about the purpose of the procedure and about the expected result
  126. (especially around boundaries).  The header often contributes to a optimization
  127. of the development because it forces you to think and to get a general view of
  128. the procedure belonging to the header.
  129.  
  130. Example of a header:
  131.  
  132. ;------------------------------------------------------------------
  133. ;       @DoFormat
  134. ;------------------------------------------------------------------
  135. ;
  136. ; Convert a string using Exec.RawDoFmt().
  137. ;
  138. ; D0 [Output] will point to the formatted string, which is the
  139. ; buffer specified by A3 [Input]. Since A3 currently is restored
  140. ; you can use either D0 or A3 to get the string, but for the sake
  141. ; of compatibility use D0.
  142. ;
  143. ;------------------------------------------------------------------
  144. ; IN    a1.l    = ^String
  145. ;       a2.l    = ^List of Arguments
  146. ;       a3.l    = ^Text Buffer
  147. ; USED  -
  148. ; OUT   d0.l    = ^Formatted String
  149. ;------------------------------------------------------------------
  150.  
  151. DoFormat:
  152.         ...
  153.         rts
  154.  
  155.  
  156. Remarks of the example above:
  157.  
  158. o The character "@" is used as a keyword for searching (more about this in the
  159.   "7. Final Word" chapter).
  160.  
  161. o I took the character "^" from Pascal where it represents a pointer (APTR).
  162.   This means "^String" is a POINTER TO String (C-fanatics will recognize the
  163.   character "*").
  164.  
  165. o If no INput or OUTput is specified, it is noted by the character "-" instead
  166.   of the registers. Is there another INput/OUTput than the registers, i.e. an
  167.   array, it is surrounded by the characters "{" and "}".
  168.  
  169. o USED is used by many, but personally I'm to lazy to check which registers
  170.   have been used. It should only be used to specify registers which are changed
  171.   by the procedure.
  172.  
  173. o I prefer to write the majority of my comments and labels in english, since it
  174.   is the computerlanguage. I strongly urge others (non-english) also to do so.
  175.  
  176.  
  177. Template of a header:
  178.  
  179. ;------------------------------------------------------------------
  180. ;       @<Name>
  181. ;------------------------------------------------------------------
  182. ;
  183. ; ???
  184. ;
  185. ;------------------------------------------------------------------
  186. ; IN    ???
  187. ;       { ??? }
  188. ; USED  ???
  189. ; OUT   ???
  190. ;       { ??? }
  191. ;------------------------------------------------------------------
  192.  
  193. The midmost and the last section of the header may optionally be skiped if
  194. they are not used.
  195.  
  196.  
  197. When you use a header, it is not so important to use inline comments (those
  198. placed after the instructions).  Inline comments are only used if some
  199. instructions require an extra description or to refer to certain parts of a
  200. possible pseudocode.
  201.  
  202. Even though the comments have to be significant and descriptive, they don't
  203. have to be boring.  Try to vary your language.  I often used citations to spice
  204. my source.  The citations must however have a relation to what they must
  205. comment.  As example I could mention a citation from the movie Blade Runner:
  206. "Wake up, time to die" as a comment to a software reset.
  207.  
  208.  
  209. *******************************************************************************
  210.                                  3. Procedures
  211. *******************************************************************************
  212.  
  213. To find a name for a label may be done in countless ways and especially if a
  214. label is compounded of more words.  The underscore (_) is often used to
  215. seperate the words, because a space normally can't be used in labels:
  216.  
  217.         my_label:               or              MY_LABEL:
  218.  
  219. The guidelines for programming in Modula-2 gives us an alternative to the ugly
  220. underscore.  Instead of seperating the words with underscores, all words are
  221. written in lowercase and the first letter of each word is capitalized:
  222.  
  223.         MyLabel:
  224.  
  225. This offers us a whole new prospecive.  It is important to be consistent with
  226. the use of capital letters.  Some assemblers offers as an option not to
  227. distinguish between the case of the letters.  My advise:  Turn this option off!
  228. Also, never use the same word with different cases.
  229.  
  230. In assembly language it can be difficult to distinguish if a certain label
  231. refers to a procedure or a variable, as they are written in the same way
  232. (namely "Label:").
  233.  
  234. We now define that all procedure must start with an uppercase letter, and all
  235. variables must start with a lowercase letter:
  236.  
  237.         MyProcedure:
  238.  
  239.         myVariable:
  240.  
  241. Now it is easy to see what type our label is, without having to jump back and
  242. forth in our source all the time.  Furthermore we shall extend the definition
  243. of variables later on.
  244.  
  245. Most assemblers supports the use of local labels (in case of doubt, look in
  246. your manual).  If you use a local label it is only known until the assembler
  247. encounters the next normal label.  Local labels are only used in procedures.
  248. This way it is possible to use a name in different procedures, whereby we avoid
  249. all these "loop1", "loop2" etc.  Therefore, use local labels in the procedures
  250. as often as possible (Save the environment!  Recycle!  ;-)
  251.  
  252. Example of local labels:
  253.  
  254.         FirstProc:
  255.                 lea     text,a0
  256.                 move.w  #10,d0
  257.         .Loop   tst.b   (a0)+
  258.                 beq.s   .Exit
  259.                 dbra    d0,.Loop
  260.         .Exit   rts
  261.  
  262.         SecondProc:
  263.                 lea     text,a0
  264.                 move.w  #10,d0
  265.         .Loop   clr.b   (a0)+
  266.                 dbra    d0,.Loop
  267.                 rts
  268.  
  269.  
  270. Even though local labels theoretically also may be used as variable, it is too
  271. troublesome in reality, where they consequently seldom are used.
  272.  
  273.  
  274. *******************************************************************************
  275.                                  4. Variables
  276. *******************************************************************************
  277.  
  278. We now extend the convention concerning variables, inspired by the "Hungarian
  279. Convertion" (developed by some guy at Microsoft).  This method is particularly
  280. aimed at assembly programmers - because it is the language I have the biggest
  281. experience with, and I don't want to force some weird, untested convention on
  282. other programming languages - but other programmers may gain advantage of the
  283. corresponding principles.  First and foremost:
  284.  
  285.                ALL VARIABLES MUST START WITH A TYPE DESCRIPTION!
  286.  
  287. This type gives us information about the concerning variable.  This way we
  288. avoid jumping back and forth in the source, to determine for example whether a
  289. variable is word or byte sized.  This type could be "p" for "Pointer" or "w" or
  290. "Word":
  291.  
  292.         pDosBase        = Pointer (APTR) to DosBase
  293.         wIntReq         = Interrupt Request (size = Word)
  294.  
  295. I have reached the following practical types, during longer time of experiments
  296. and daily use:
  297.  
  298.         b       =       Byte
  299.         w       =       Word
  300.         l       =       Long
  301.         p       =       Pointer [APTR]
  302.         h       =       Handler [BPTR]
  303.         f       =       Flag
  304.         a       =       Array
  305.         s       =       String [Array of Chars]
  306.         d       =       (Arbitrary) Data Structure
  307.         x       =       Extern Data [ex: Binary/Modules/Pictures]
  308.         i       =       Index / Offset
  309.         u       =       Unsigned
  310.         v       =       Local Data [ex: Variables on Stack]
  311.  
  312. Please remember:  the type must be placed in front of the variable and
  313. consequently must be written in lowercase to comply with the principle of the
  314. distinction of procedures and variables from the previous chapter.
  315.  
  316. Of course, it is possible to combine some of the types to reach a better
  317. clarification.  This could be:
  318.  
  319.         ub      =       UBYTE (Unsigned Byte)
  320.         uw      =       UWORD
  321.         ul      =       ULONG
  322.         fl      =       Flag Long
  323.         iw      =       Index Word
  324.         ap      =       Array of Pointers
  325.         ab      =       Array of Bytes
  326.         afb     =       Array of Flag Bytes
  327.         auw     =       Array of UWORD
  328.  
  329. Some of the types are very unlikely to appear in these combinations (though
  330. they might):
  331.  
  332.    "d" covers arbitrary data structures, like Window and Screen structures.
  333.    "x" covers external binary files, like tables, pictures and music-modules.
  334.  
  335. All of the types may be combined with "v", which indicates local data, like
  336. variables on the stack.  Some of the types, like "x" are however rather
  337. unlikely to appear together with "v".
  338.  
  339. NB!  "v" doesn't make a variable local, it only indicates that the variable
  340.      should be used in a local context.
  341.  
  342.  
  343. Examples of variables:
  344.  
  345.         fbDelay         dc.b    -1
  346.         iwSinus:        dc.w    22      ;Index for Sinus Table
  347.         hFile:          dc.l    0       ;File Handle [BPTR]
  348.         awBuffer:       dcb.w   20,0
  349.         dWindow:        dcb.b   nw_SIZE,0
  350.         xMusic:         INCBIN  "ST-00:mod.freudian"
  351.  
  352.  
  353. *******************************************************************************
  354.                                  5. Constants
  355. *******************************************************************************
  356.  
  357. Constants are classified as variables, but they have their own type:
  358.  
  359.         c       =       Constant
  360.  
  361. There is nothing much to add about the constants as they are only a subtype of
  362. the variables in this convention.  It is also possible to combine the constant
  363. type with some of the variable types.
  364.  
  365. Examples of constants:
  366.  
  367.         cMaxSize        = 128
  368.         clAddressAlert  = $00000003
  369.         ciFirstEntry    = 44
  370.  
  371.  
  372. *******************************************************************************
  373.             6. Various (Instructions, Assembly Directives & Macros)
  374. *******************************************************************************
  375.  
  376. The last definitions we need to complete this convention are about the
  377. instructions, the assembly directives and the macros.  They must also be
  378. unique, to make the the convention effective.
  379.  
  380. We define all instruction to solely consist of lowercase letters, and the
  381. assembly directives and the macros to solely consist of uppercase letters.  The
  382. only exceptions are the dc/ds/dcb directives which of comprehensibility reasons
  383. are classified as instructions.
  384.  
  385. Macros are often used to facilitate the readabillity of sources.  For instance:
  386.  
  387.  
  388. Execute a function in an arbitrary library
  389. -------------------------------------------------------------------------------
  390. Syntax: CALL    <Library function>
  391.  
  392. Ex:     CALL    Forbid          =       jsr     _LVOForbid(a6)
  393.  
  394.  
  395. Push registers to the stack
  396. -------------------------------------------------------------------------------
  397. Syntax: PUSH    <Registers>
  398.  
  399. Ex:     PUSH    d0/a0-a4        =       movem.l d0/a0-a4,-(sp)
  400.  
  401.  
  402. Pull registers from the stack
  403. -------------------------------------------------------------------------------
  404. Syntax: PULL    <Registers>
  405.  
  406. Ex:     PULL    d0/a0-a4        =       movem.l (sp)+,d0/a0-a4
  407.  
  408.  
  409.  
  410. *******************************************************************************
  411.                                 7. Final Words
  412. *******************************************************************************
  413.  
  414. Then using modules (linkable object code) we have to specify external
  415. references of both procedures and variables.  These are specified by using an
  416. underscore (_) at the first position of the label:
  417.  
  418.         XREF    _LVOAddTask
  419.         XDEF    _ClearScreen
  420.  
  421. [NOTE 2] contains a complete example of a source documented using this
  422. convention.  It is an old source of mine which I have updated to comply with
  423. the principles of the convention.
  424.  
  425. It is unfortunately not possible to use this convention a 100%.  We get a
  426. problem when we use the includes from Commodore.  It is a bad idea however to
  427. change the includes, but if we are attentive of this problem we may live with
  428. this restriction.  Besides, I diverge from the principles of the convention in
  429. two specific points:  "start" and "DataArea" (no rule without exception).
  430. These are however the ONLY exceptions!  If you absolutely have to be
  431. inconsistent, when be consistent with the inconsistent!
  432.  
  433. Another advise I will pass is not to choose a name for a label that is too
  434. difficult to spell or too hard to remember.  Choose easy names.  I have for
  435. instance always thought that words like "width", "height" and "depth" have
  436. increased the possibility for spelling mistakes.  Hence I substituted the words
  437. with the following words:  "xSize", "ySize" and "zSize".
  438.  
  439. If you are working with a big source, you may define keywords for all the
  440. procedures, which may be placed in the header.  This should speed up the search
  441. for a specific procedure.  To avoid the searching to stop at each reference of
  442. the procedure (i.e.  each time it is called or jumped to), you could let the
  443. keyword start with the character "@".  If I want to find the "NewMenu"
  444. procedure, I have to search for "@NewMenu".
  445.  
  446. The convention described in this text is only a couple of guidelines, and it is
  447. up to you, whether you will use them or not, but since I started using them and
  448. became familiar with them, my development- and debugging time has been hugely
  449. reduced.  [NOTE 1] consists of a template which I use in my own programs
  450. (written for AsmOne - if you use another assembler delete the BASEREG line).
  451. The template may vary a little, depending on the type of program I have to
  452. write.
  453.  
  454. Remember! Not matter what you do: BE CONSISTENT.
  455.  
  456.  
  457.         - BReese
  458.  
  459.  
  460. My address is
  461.  
  462.         Bjørn Reese
  463.         Stammen 55, -2
  464.         DK-5220 Odense SØ
  465.         Denmark
  466.  
  467.  
  468.  
  469.  
  470. *******************************************************************************
  471.                                    [NOTE 1]
  472. *******************************************************************************
  473.  
  474. ;==================================================================
  475. ;===
  476. ;===    Name:   ???
  477. ;===
  478. ;===    Author: ???
  479. ;===
  480. ;===    Date:   dd. mmm yyyy
  481. ;===
  482. ;==================================================================
  483.  
  484.  
  485. ;--- Comment ------------------------------------------------------
  486. ;
  487. ; TAB = 8       ;       POINTER = ^
  488. ;
  489. ;------------------------------------------------------------------
  490.  
  491.  
  492. ;--- System -------------------------------------------------------
  493.  
  494.         BASEREG DataArea,a5
  495.         INCDIR  INCLUDE:
  496.  
  497. ;--- Include ------------------------------------------------------
  498.  
  499. ;--- Macro --------------------------------------------------------
  500.  
  501. ;--- Constant -----------------------------------------------------
  502.  
  503.  
  504.  
  505. ;==================================================================
  506. ;===
  507. ;===    CODE AREA
  508. ;===
  509. ;==================================================================
  510.  
  511.         SECTION Reese,CODE
  512.  
  513. start:
  514.         moveq   #0,d0
  515.         rts
  516.  
  517.  
  518. ;------------------------------------------------------------------
  519. ;       @<Name>
  520. ;------------------------------------------------------------------
  521. ;
  522. ; ???
  523. ;
  524. ;------------------------------------------------------------------
  525. ; IN    ???
  526. ;       { ??? }
  527. ; OUT   ???
  528. ;       { ??? }
  529. ;------------------------------------------------------------------
  530.  
  531.  
  532.  
  533. ;==================================================================
  534. ;===
  535. ;===    DATA AREA
  536. ;===
  537. ;==================================================================
  538.  
  539. ;--- Structure ----------------------------------------------------
  540.  
  541. ;--- SmallCode ----------------------------------------------------
  542.  
  543. ;--- Variable -----------------------------------------------------
  544.  
  545. DataArea:
  546.  
  547.  
  548. ;--- Text ---------------------------------------------------------
  549.  
  550. ;--- Table --------------------------------------------------------
  551.  
  552. ;--- Extern -------------------------------------------------------
  553.  
  554.  
  555. ;==================================================================
  556. ;===
  557. ;===    BUFFER AREA
  558. ;===
  559. ;==================================================================
  560.  
  561. ;       SECTION buffer,BSS
  562.  
  563.  
  564.  
  565. *******************************************************************************
  566.                                    [NOTE 2]
  567. *******************************************************************************
  568.  
  569. ;==================================================================
  570. ;===
  571. ;===    Name:   CountSort  (Sort an array of integers)
  572. ;===
  573. ;===    Author: Bjørn Reese
  574. ;===
  575. ;===    Date:   January 1991
  576. ;===
  577. ;==================================================================
  578. ;===
  579. ;===    Copyright © 1991 by Bjørn Reese
  580. ;===
  581. ;==================================================================
  582.  
  583.  
  584. ;--- Comment ------------------------------------------------------
  585. ;
  586. ; TAB = 8       ;       POINTER = ^
  587. ;
  588. ; The numbers in awNumbers are sorted.
  589. ; NB! cMaxNum must be equal to or greater than the biggest number
  590. ;   in awNumbers.
  591. ;
  592. ;------------------------------------------------------------------
  593.  
  594.  
  595. ;--- System -------------------------------------------------------
  596.  
  597.         BASEREG DataArea,a5
  598.         INCDIR  INCLUDE:
  599.  
  600. ;--- Constant -----------------------------------------------------
  601.  
  602. cMaxNum = 32    ;Biggest number in awNumbers ( [0..cMaxNum-1] )
  603. cLength = 16    ;Numbers of words in awNumbers
  604.  
  605.  
  606. ;==================================================================
  607. ;===
  608. ;===    CODE AREA
  609. ;===
  610. ;==================================================================
  611.  
  612.         SECTION CountSort,CODE
  613.  
  614. start:
  615.  
  616. ;--- Do the entire sorting
  617.  
  618.         bsr     ClearBuffer
  619.         bsr     Count
  620.         bsr     CountResult
  621.  
  622. ;--- Exit without error messages
  623.  
  624.         moveq   #0,d0
  625.         rts
  626.  
  627.  
  628. ;------------------------------------------------------------------
  629. ;       @ClearBuffer
  630. ;------------------------------------------------------------------
  631. ;
  632. ; Clear awCountBuffer before use.
  633. ; cMaxNum must be even.
  634. ;
  635. ;------------------------------------------------------------------
  636. ; IN    -
  637. ; USED  d0/d1/a0
  638. ; OUT   -
  639. ;       { awCountBuffer empty }
  640. ;------------------------------------------------------------------
  641.  
  642. ClearBuffer:
  643.         lea     awCountBuffer,a0
  644.         moveq   #0,d0
  645.         move.w  #cMaxNum/2-1,d1
  646. .Loop   move.w  d0,(a0)+
  647.         move.w  d0,(a0)+
  648.         dbra    d1,.Loop
  649.         rts
  650.  
  651. ;------------------------------------------------------------------
  652. ;       @Count
  653. ;------------------------------------------------------------------
  654. ;
  655. ; Counts the appearence of the numbers in awNumbers and accumulate
  656. ; CountBuffer
  657. ;
  658. ;  FOR cnt = 0 TO cLength-1
  659. ;    num := awNumbers[cnt]
  660. ;    awCountBuffer[num] += 1
  661. ;  NEXT
  662. ;
  663. ; NB!!! [] indicates index (ex: Array[index])
  664. ;
  665. ;------------------------------------------------------------------
  666. ; IN    -
  667. ;       { Emtpy awCountBuffer }
  668. ; USED  d0/d1/a0/a1
  669. ; OUT   -
  670. ;       { awCountBuffer accumulated }
  671. ;------------------------------------------------------------------
  672.  
  673. Count:
  674.         lea     awNumbers(pc),a0
  675.         lea     awCountBuffer,a1
  676.         move.w  #cLength-1,d1
  677. .Loop   move.w  (a0)+,d0
  678.         add.w   d0,d0           ;Adjust to word boundary
  679.         addq.w  #1,(a1,d0.w)    ;awCountBuffer[num] += 1
  680.         dbra    d1,.Loop
  681.         rts
  682.  
  683. ;------------------------------------------------------------------
  684. ;       @MakeResult
  685. ;------------------------------------------------------------------
  686. ;
  687. ; Stores numbers in awNumbers according to numbers in awCountBuffer.
  688. ;
  689. ;  cnt2 := 0
  690. ;  FOR cnt = 0 TO cMaxNum-1
  691. ;    WHILE awCountBuffer[cnt] > 0
  692. ;      awNumbers[cnt2] := cnt
  693. ;      awCountBuffer[cnt] -= 1
  694. ;      cnt2 += 1
  695. ;    WEND
  696. ;  NEXT
  697. ;
  698. ; NB!!! The code has been optimized, so it doesn't look like the
  699. ; pseudocode above, but it's based on it. cLength is used instead
  700. ; of cMaxNum.
  701. ;
  702. ;------------------------------------------------------------------
  703. ; IN    -
  704. ;       { Accumulated awCountBuffer }
  705. ; USED  d0/d1/d2/a0/a1
  706. ; OUT   -
  707. ;       { awNumbers sorted }
  708. ;------------------------------------------------------------------
  709.  
  710. MakeResult:
  711.         lea     awCountBuffer,a0
  712.         lea     awNumbers(pc),a1
  713.         moveq   #0,d0
  714.         move.w  #cLength-1,d1
  715.         bra.s   .Loop
  716. .Next   addq.w  #1,d0           ;Next number
  717.         addq.w  #2,a0           ;Next entry in awCountBuffer
  718. .Loop   subq.w  #1,(a0)         ;CountArray[cnt] -= 1
  719.         blt.s   .Next
  720.         move.w  d0,(a1)+
  721.         dbra    d1,.Loop
  722.         rts
  723.  
  724.  
  725. ;==================================================================
  726. ;===
  727. ;===    DATA AREA
  728. ;===
  729. ;==================================================================
  730.  
  731. ;--- Variable -----------------------------------------------------
  732.  
  733. DataArea:
  734.  
  735.  
  736. ;--- Table --------------------------------------------------------
  737.  
  738. awNumbers:      ;An example
  739.         dc.w    5,22,6,31,5,1,3,3,5,6,7,25,15,9,0,21
  740.  
  741.  
  742. ;==================================================================
  743. ;===
  744. ;===    BUFFER AREA
  745. ;===
  746. ;==================================================================
  747.  
  748.         SECTION buffer,BSS
  749.  
  750. awCountBuffer   ds.w    cMaxNum
  751.  
  752.  
  753. *******************************************************************************
  754.                                    [NOTE 3]
  755. *******************************************************************************
  756.  
  757. ;==================================================================
  758. ;===
  759. ;===    Name:   Another test example (which finds Dos Library)
  760. ;===
  761. ;===    Author: Bjørn Reese
  762. ;===
  763. ;===    Date:   October 1991
  764. ;===
  765. ;==================================================================
  766.  
  767.  
  768. ;--- Comment ------------------------------------------------------
  769. ;
  770. ; TAB = 8       ;       POINTER = ^
  771. ;
  772. ; a5 is a global pointer to the DataArea.
  773. ;
  774. ;------------------------------------------------------------------
  775.  
  776.  
  777. ;--- System -------------------------------------------------------
  778.  
  779.         BASEREG DataArea,a5
  780.         INCDIR  INCLUDE:
  781.  
  782. ;--- Include ------------------------------------------------------
  783.  
  784.         INCLUDE exec/exec_lib.i
  785.         INCLUDE exec/execbase.i
  786.  
  787. ;--- Macro --------------------------------------------------------
  788.  
  789. CALL:   MACRO
  790.         jsr     _LVO\1(a6)
  791.         ENDM
  792.  
  793.  
  794. ;--- Constant -----------------------------------------------------
  795.  
  796. cSysBase        = 4
  797.  
  798.  
  799. ;==================================================================
  800. ;===
  801. ;===    CODE AREA
  802. ;===
  803. ;==================================================================
  804.  
  805. start:
  806.         lea     DataArea(pc),a5         ;GLOBAL
  807.  
  808.         lea     sDosName(a5),a1
  809.         bsr     GetLibrary
  810.         move.l  d0,pDosBase(a5)
  811.  
  812.         moveq   #0,d0
  813.         rts
  814.  
  815. ;------------------------------------------------------------------
  816. ;       @GetLibrary
  817. ;------------------------------------------------------------------
  818. ;
  819. ; Find an already opened and initialized library in the LibList
  820. ; of Exec Library.
  821. ;
  822. ; NB!!! Only use this method for ROM-resident Libraries.
  823. ;
  824. ;------------------------------------------------------------------
  825. ; IN    a1.l    = ^Library Name
  826. ; OUT   d0.l    = ^Library Base
  827. ;------------------------------------------------------------------
  828.  
  829. GetLibrary:
  830.         move.l  cSysBase,a6
  831.         move.l  LibList(a6),a0
  832.         CALL    FindName
  833.         rts
  834.  
  835. ;==================================================================
  836. ;===
  837. ;===    DATA AREA
  838. ;===
  839. ;==================================================================
  840.  
  841. ;--- Variable -----------------------------------------------------
  842.  
  843. DataArea:
  844. pDosBase:       dc.l    0
  845.  
  846. ;--- Text ---------------------------------------------------------
  847.  
  848. sDosName:       dc.b    'dos.library',0
  849.                 EVEN
  850.  
  851.  
  852. *******************************************************************************
  853.                                    [NOTE 4]
  854. *******************************************************************************
  855.  
  856.       Types           Meaning
  857.     ------------------------------------------------------------------
  858.         b       =       Byte
  859.         w       =       Word
  860.         l       =       Long
  861.         p       =       Pointer [APTR]
  862.         h       =       Handler [BPTR]
  863.         f       =       Flag
  864.         a       =       Array
  865.         s       =       String [Array of Chars]
  866.         d       =       (Arbitrary) Data Structure
  867.         x       =       Extern Data [ex: Binary/Modules/Pictures]
  868.         i       =       Index / Offset
  869.         u       =       Unsigned
  870.         v       =       Local Data [ex: Variables on Stack]
  871.         c       =       Constant
  872.     ------------------------------------------------------------------
  873.